package com.niuwa.p2p.service.impl.business;


import java.math.BigDecimal;
import java.sql.Timestamp;
import java.text.Format;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.niuwa.p2p.core.mvc.entity.JsonResult;
import com.niuwa.p2p.core.mvc.entity.PageBean;
import com.niuwa.p2p.core.utils.AppConstants;
import com.niuwa.p2p.core.utils.DictConstant;
import com.niuwa.p2p.core.utils.DictConstant.ProductIdType;
import com.niuwa.p2p.dao.business.LoanClaimDao;
import com.niuwa.p2p.dao.business.PlanProductDao;
import com.niuwa.p2p.dao.business.ProdAuditDao;
import com.niuwa.p2p.dao.business.ProdRelativeProtDao;
import com.niuwa.p2p.dao.productTemplate.ProductDao;
import com.niuwa.p2p.dao.productTemplate.TemplateProtocolDao;
import com.niuwa.p2p.dao.protocol.ProtocolDao;
import com.niuwa.p2p.entity.PageQuery;
import com.niuwa.p2p.entity.business.ProdAudit;
import com.niuwa.p2p.entity.business.ProdRelativeProt;
import com.niuwa.p2p.entity.productTemplate.Product;
import com.niuwa.p2p.service.business.PlanProductService;
import com.niuwa.p2p.service.productTemplate.ProductService;
import com.niuwa.p2p.utils.DateFormatUtils;
import com.niuwa.p2p.vo.business.InvestPlanProductVo;
import com.niuwa.p2p.vo.business.LoanClaimOriginVo;
import com.niuwa.p2p.vo.business.PlanVo;
import com.niuwa.p2p.vo.front.product.FrontProductDetailVo;
import com.niuwa.p2p.vo.front.product.FrontProductListVo;

@Service
public class PlanProductServiceImpl implements PlanProductService {
	
	@Autowired
	private PlanProductDao planProductDao;
	
	@Autowired
	private ProductDao productDao;
	
	@Autowired
	private ProtocolDao protocolDao;
	
	
	@Autowired
	private TemplateProtocolDao templateProtocolDao;
	
	@Autowired
	private ProdRelativeProtDao prodRelativeProtDao;
	
	@Autowired
	private ProdAuditDao prodAuditDao;
	
	@Autowired
	private ProductService productService;
	
	@Autowired
	private LoanClaimDao loanClaimDao;
	
	protected static Format format = new SimpleDateFormat("");
	
	@Override
	public JsonResult saveInvestPlanProduct(InvestPlanProductVo planProduct) {
		JsonResult jsonResult=new JsonResult(false,"创建投资计划异常!");
		try {
			//产品信息
			Product product=new Product();
			BeanUtils.copyProperties(planProduct,product);
			
			//投资计划信息
			PlanVo planVo=new PlanVo();
			BeanUtils.copyProperties(planProduct,planVo);
			
			SimpleDateFormat sf=new SimpleDateFormat("yyyy-MM-dd");
			SimpleDateFormat sft=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			String tempTime=sf.format(product.getReleaseTime())+" "+planProduct.getReleaseTimeHr()+":00:00";
			Timestamp date=new Timestamp(sft.parse(tempTime).getTime());
			product.setReleaseTime(date);//组合发布时间
			tempTime=sf.format(product.getStartSellTime())+" "+planProduct.getStartSellTimeHr()+":00:00";
			date=new Timestamp(sft.parse(tempTime).getTime());
			product.setStartSellTime(date);//组合起售时间
			product.setEndSellTime(acquireEndSellTime(planProduct));//计算停售时间
			product.setRemainAmount(planVo.getCollectAmount());//剩余金额[默认募集规模]
			
			int pResult,ippResult;//影响行数
			
			if (StringUtils.isBlank(planProduct.getProductCode())) {
				planVo.setProdStatus(DictConstant.ReleaseStatus.WAIT_APPLY.getCode());//默认待申请
				String prodCode=productService.getNewProductId(ProductIdType.CPJH);//投资计划产品编码
				product.setProductCode(prodCode);//产品编码
				product.setCreateTime(new Date());//创建时间
				product.setCompletedProgress(new BigDecimal(0.00));//完成进度[默认0.00%]
				pResult=productDao.saveProduct(product);
				
				planVo.setProductCode(prodCode);//产品编码
				//planVo.setRemainAmount(planVo.getCollectAmount());//剩余金额[默认募集规模]
				ippResult=planProductDao.saveInvestPlanProduct(planVo);
				
				if ((pResult+ippResult)>1) {
					jsonResult=new JsonResult(true,"创建投资计划成功!");
				}
			}else{
				Map<String, Object> paramMap=new HashMap<String, Object>();
				paramMap.put("productCode", planProduct.getProductCode());
				paramMap.put("oldProdStatus",planProduct.getOldProdStatus());//投资计划原始状态
				//根据状态、编码去找信息
				InvestPlanProductVo planProd=planProductDao.getInvestPlanByCodeStatus(paramMap);
				if(planProd!=null){
					pResult=productDao.updateProduct(product);
					ippResult=planProductDao.updateInvestPlanProduct(planVo);
					
					if ((pResult+ippResult)>1) {
						jsonResult=new JsonResult(true,"修改投资计划成功!");
					}
				}else{
					jsonResult=new JsonResult(false,"该信息状态已变，请刷新页面重试!");
				}
			}
			//投资计划协议
			prodRelativeProtDao.deleteProdRelativeProtByProd(product.getProductCode());
			if (null!=planProduct.getProtId() && planProduct.getProtId().length>0) {
				List<ProdRelativeProt> prp=formatTempProt(product.getProductCode(),planProduct.getProtId());
				prodRelativeProtDao.saveProdRelativeProt(prp);
			}
		} catch (Exception e) {
			// TODO: LOG
			e.printStackTrace();
		}
		return jsonResult;
	}
	
	/**
	 * 新增选中的协议信息列表
	 * 
	 * @param tempId
	 * @param form
	 */
	private List<ProdRelativeProt> formatTempProt(String prodCode, String[] protId) {
		List<ProdRelativeProt> tpList = new ArrayList<ProdRelativeProt>();
		for (int index = 0; index < protId.length; index++) {
			ProdRelativeProt tp = new ProdRelativeProt();
			tp.setProd(prodCode);
			if(null != protId[index] && !"".equals(protId[index]))
				tp.setProtId(Long.valueOf(protId[index]));
			tpList.add(tp);
		}
		return tpList;
	}

	/**
	 * 查询符合条件的投资计划
	 */
	@Override
	public PageBean<InvestPlanProductVo> selectInvestPlanBySelective(
			Map<String, Object> paramMap) {
		assert paramMap.get(PageQuery.PAGEQUERY) != null;
		//发布时间区间
		String startDate = (String) paramMap.get("startDate");
		if (StringUtils.isNotBlank(startDate))
			paramMap.put("startDate", startDate.concat(" 00:00:00"));
		String endDate = (String) paramMap.get("endDate");
		if (StringUtils.isNotBlank(endDate))
			paramMap.put("endDate", endDate.concat(" 23:59:59"));
		int totalCount = planProductDao.selectInvestPlanCountBySelective(paramMap);
		PageBean<InvestPlanProductVo> page = new PageBean<InvestPlanProductVo>(totalCount);
		page.setPage(((PageQuery) paramMap.get(PageQuery.PAGEQUERY)).getPage());
		page.setRows(planProductDao.selectInvestPlanBySelective(paramMap));
		return page;
	}


	@Override
	public InvestPlanProductVo getInvestPlanBySelective(InvestPlanProductVo planProduct) {
		Map<String, Object> paramMap=new HashMap<String, Object>();
		paramMap.put("productCode", planProduct.getProductCode());
		InvestPlanProductVo productVo=planProductDao.getInvestPlanBySelective(paramMap);
		// 获取协议信息
		productVo.setProductProtocols(protocolDao.getProdRelativeProt(productVo.getProductCode()));
		//获取债权列表
		List<LoanClaimOriginVo> originVos=loanClaimDao.getClaimListByProdCode(planProduct.getProductCode());
		productVo.setOriginVos(originVos);
		return productVo;
	}

	//获取停售时间
	private Date acquireEndSellTime(InvestPlanProductVo planProduct){
		Date date=null;
		try {
			SimpleDateFormat sf=new SimpleDateFormat("yyyy-MM-dd");
			SimpleDateFormat sft=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			//有效时间
			Integer validTerm=planProduct.getValidTerm();
			String validTermType=planProduct.getValidTermType();
			if (validTerm!=null && StringUtils.isNotBlank(validTermType)) {
				//起售时间
				Date startSellTime=planProduct.getStartSellTime();
				int day=0;
				if (DictConstant.TermType.D.getCode().equals(validTermType)) {
					day=validTerm;
				}else if(DictConstant.TermType.M.getCode().equals(validTermType)){
					day=validTerm*30;	//TODO待定30
				}else if(DictConstant.TermType.Y.getCode().equals(validTermType)){
					day=validTerm*365;	//TODO待定365
				}
				date=DateFormatUtils.getAppointedDayAfterDay(startSellTime,day);
				String tempTime=sf.format(date)+" "+planProduct.getStartSellTimeHr()+":00:00";
				date=new Timestamp(sft.parse(tempTime).getTime());
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return date;
	}

	
	@Override
	public JsonResult updateInvestPlanStatus(InvestPlanProductVo planProduct,ProdAudit prodAudit) {
		JsonResult jsonResult=new JsonResult(false,"操作异常!");
		try {
			Map<String, Object> paramMap=new HashMap<String, Object>();
			paramMap.put("productCode", planProduct.getProductCode());
			paramMap.put("oldProdStatus",planProduct.getOldProdStatus());//投资计划原始状态
			//根据状态、编码去找信息
			InvestPlanProductVo planProd=planProductDao.getInvestPlanByCodeStatus(paramMap);
			if(planProd!=null){
				paramMap.put("prodStatus", getProdStatus(prodAudit.getOperateType()));
				prodAudit.setProdCode(planProduct.getProductCode());
				prodAudit.setCreateTime(new Date());
				
				int result=planProductDao.updateInvestPlanStatus(paramMap);
				int resultT=prodAuditDao.addProdAudit(prodAudit);
				if (prodAudit.getOperateType().equals(AppConstants.PASS)
						|| prodAudit.getOperateType().equals(AppConstants.REJECT)) {
					Product product=productDao.getProductByProdCode(planProduct.getProductCode());
					if (null!=product) {
						product.setAuditor(prodAudit.getOperator());;
						productDao.updateProduct(product);//审核人
					}
				}
				if (result+resultT>1) {
					jsonResult=new JsonResult(true,"操作成功!");
				}else{
					jsonResult=new JsonResult(false,"操作失败!");
				}
			}else{
				jsonResult=new JsonResult(false,"该信息状态已变，请刷新页面重试!");
			}
		} catch (Exception e) {
			// TODO: LOG
			e.printStackTrace();
		}
		return jsonResult;
	}
	
	/**
	 * 获取产品状态
	 * @param operateType
	 */
	private String getProdStatus(String operateType){
		String prodStatus="";
		switch (operateType) {
		case AppConstants.APPLY_RELEASE://发布申请
			prodStatus=DictConstant.ReleaseStatus.WAIT_AUDIT.getCode();//待审核
			break;
		case AppConstants.PASS://通过
			prodStatus=DictConstant.ReleaseStatus.WAIT_RELEASE.getCode();//待发布
			break;
		case AppConstants.REJECT://拒绝
			prodStatus=DictConstant.ReleaseStatus.NO_PASS.getCode();//未通过
			break;
		case AppConstants.STOP_RELEASE://中止发布
			prodStatus=DictConstant.ReleaseStatus.NO_PASS.getCode();//未通过
			break;
		case AppConstants.STOP_USE://下线
			prodStatus=DictConstant.ReleaseStatus.OFFLINE.getCode();//已下线
			break;
		default:
			break;
		}
		return prodStatus;
	}

	
	//====================== 前台使用  Add by bwz begin ==============================
	@Override
	public List<FrontProductListVo> selectPlanProductListPage(Map<String, Object> paramMap) throws Exception {
		List<FrontProductListVo> list = planProductDao.selectPlanProductListPage(paramMap);
		return list;
	}
	
	
	@Override
	public FrontProductDetailVo getPlanProductDetail(Map<String, Object> paramMap) {
		FrontProductDetailVo fProdDetailVo = planProductDao.getPlanProductDetail(paramMap);
		return fProdDetailVo;
	}

	
	@Override
	public List<FrontProductListVo> selectHotProduct(Map<String, Object> paramMap) {
		List<FrontProductListVo> hotProdList = planProductDao.selectHotProduct(paramMap);
		return hotProdList;
	}

	@Override
	public List<FrontProductListVo> selectHotProduct4New(Map<String, Object> paramMap) {
		List<FrontProductListVo> hotProdList = planProductDao.selectHotProduct4New(paramMap);
		return hotProdList;
	}


	
	
	//====================== 前台使用  Add by bwz end =================================
	
	@Override
	public FrontProductListVo selectProdNewForIndex() {
		return planProductDao.selectProdNewForIndex();
	}

	@Override
	public List<FrontProductListVo> selectProdPlanForIndex() {
		return planProductDao.selectProdPlanForIndex();
	}
	
	
}
